package pruebas;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.PrintStream;
import java.util.ArrayList;

import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerConfigurationException;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.TransformerFactoryConfigurationError;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;

import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.xml.sax.SAXException;

import juego.AvionCivil;
import juego.Botin;
import juego.Colateral;
import juego.Coordenada;
import juego.Energia;
import juego.Helicoptero;
import juego.Impacto;
import juego.Laser;
import juego.Movil;
import juego.Torpedo;
import junit.framework.TestCase;


public class TestAvionCivil extends TestCase {
	
	public void testMovimiento(){
		
		ArrayList<Movil> listaDeMoviles = new ArrayList<Movil>();
		ArrayList<Botin> listaDeBotines = new ArrayList<Botin>();
		Colateral avion = new AvionCivil(0,8);
		assertEquals (0, avion.verUbicacion().obtenerCoordenadaX());
		assertEquals (8, avion.verUbicacion().obtenerCoordenadaY());
		
		avion.vivir(listaDeMoviles, listaDeBotines);
		assertEquals (0, avion.verUbicacion().obtenerCoordenadaX());
		assertEquals (13, avion.verUbicacion().obtenerCoordenadaY());
	};
	
	public void testImpactoProvocado(){
		
		Colateral avion = new AvionCivil(0,8);
		Energia energia = new Energia(30);
		Impacto impacto = avion.impactoProvocado();
		impacto.herir(energia);
		assertEquals(20, energia.verEnergia());
		
	};
	
	public void testColisionEntreAvionesCiviles(){
		
		ArrayList<Movil> listaDeMoviles = new ArrayList<Movil>();
		ArrayList<Botin> listaDeBotines = new ArrayList<Botin>();
        Colateral avion = new AvionCivil(0,8);
        Colateral otroAvion = new AvionCivil(5,8);
        listaDeMoviles.add(avion);
        listaDeMoviles.add(otroAvion);
        int puntaje = avion.vivir(listaDeMoviles,listaDeBotines);
        assertEquals(0,puntaje);
        assertTrue(avion.estaVivo());
        assertTrue(otroAvion.estaVivo());
        assertEquals(2,listaDeMoviles.size());
	};
	
	public void testColisionContraHelicoptero(){
		
		ArrayList<Movil> listaDeMoviles = new ArrayList<Movil>();
		ArrayList<Botin> listaDeBotines = new ArrayList<Botin>();
        Colateral avion = new AvionCivil(0,8);
        Colateral helicoptero = new Helicoptero(5,8);
        listaDeMoviles.add(avion);
        listaDeMoviles.add(helicoptero);
        int puntaje = avion.vivir(listaDeMoviles,listaDeBotines);
        assertEquals(0,puntaje);
        assertTrue(avion.estaVivo());
        assertTrue(helicoptero.estaVivo());
        assertEquals(2,listaDeMoviles.size());
	};

	public void testColisionProyectilLeal(){
		
		ArrayList<Movil> listaDeMoviles = new ArrayList<Movil>();
		ArrayList<Botin> listaDeBotines = new ArrayList<Botin>();
		Colateral avion = new AvionCivil(0,8);
		listaDeMoviles.add(avion);
		Coordenada ubicacion = new Coordenada(8,17);
		Laser laser = new Laser(ubicacion);
		laser.hacerLeal();
		listaDeMoviles.add(laser);
		int puntaje = avion.vivir(listaDeMoviles,listaDeBotines);
		assertEquals(-300,puntaje);
		assertFalse(listaDeMoviles.contains(avion));
		assertFalse(listaDeMoviles.contains(laser));
		assertFalse(avion.estaVivo());
		assertFalse(laser.estaVivo());
	};
	
	public void testColisionProyectilNoLeal(){
		
		ArrayList<Movil> listaDeMoviles = new ArrayList<Movil>();
		ArrayList<Botin> listaDeBotines = new ArrayList<Botin>();
		Colateral avion = new AvionCivil(0,8);
		listaDeMoviles.add(avion);
		Coordenada ubicacion = new Coordenada(4,7);
		Laser laser = new Laser(ubicacion);
		listaDeMoviles.add(laser);
		int puntaje = avion.vivir(listaDeMoviles,listaDeBotines);
		assertEquals(0,puntaje);
		assertTrue(listaDeMoviles.contains(avion));
		assertTrue(listaDeMoviles.contains(laser));
		assertTrue(avion.estaVivo());
		assertTrue(laser.estaVivo());
	};
	
	public void testColisionVariosProyectiles(){
		
		ArrayList<Movil> listaDeMoviles = new ArrayList<Movil>();
		ArrayList<Botin> listaDeBotines = new ArrayList<Botin>();
		
		Coordenada ubicacion = new Coordenada(5,8);
		Laser laser = new Laser(ubicacion);
		laser.hacerLeal();
		listaDeMoviles.add(laser);
		
		Colateral avion = new AvionCivil(0,8);
		listaDeMoviles.add(avion);
				
		Laser otroLaser = new Laser(ubicacion);
		otroLaser.hacerLeal();
		listaDeMoviles.add(otroLaser);
		
		Coordenada otraUbicacion = new Coordenada(8,17);
		Torpedo torpedo = new Torpedo(otraUbicacion);
		listaDeMoviles.add(torpedo);
		
		Torpedo otroTorpedo = new Torpedo(otraUbicacion);
		otroTorpedo.hacerLeal();
		listaDeMoviles.add(otroTorpedo);
		
		
		int puntaje = avion.vivir(listaDeMoviles,listaDeBotines);
		assertEquals(-300, puntaje);
		assertFalse(avion.estaVivo());
		assertTrue(laser.estaVivo());
		assertTrue(otroLaser.estaVivo());
		assertTrue(torpedo.estaVivo());
		assertFalse(otroTorpedo.estaVivo());
		assertFalse(listaDeMoviles.contains(avion));
		assertTrue(listaDeMoviles.contains(laser));
		assertTrue(listaDeMoviles.contains(otroLaser));
		assertTrue(listaDeMoviles.contains(torpedo));
		assertFalse(listaDeMoviles.contains(otroTorpedo));
	}
	
	public void testFueraDelEscenario(){
		ArrayList<Movil> listaDeMoviles = new ArrayList<Movil>();
		ArrayList<Botin> listaDeBotines = new ArrayList<Botin>();
		
		AvionCivil avion = new AvionCivil(404,460);
		listaDeMoviles.add(avion);
		
		assertTrue((listaDeMoviles.size() == 1));
		assertTrue(avion.estaVivo());
		
		for (int i = 1; i < 4; i++){
			avion.vivir(listaDeMoviles,listaDeBotines);
		}
		
		assertTrue((listaDeMoviles.size() == 0));
		assertFalse(avion.estaVivo());
	}
	
	



	private static void persistir(String archivo, AvionCivil nave) {
		try {

			Document doc = DocumentBuilderFactory.newInstance()
					.newDocumentBuilder().newDocument();

			Element element = nave.getElement(doc);
			doc.appendChild(element);

			Transformer transformer = TransformerFactory.newInstance()
					.newTransformer();
			transformer.setOutputProperty(OutputKeys.INDENT, "yes");
			transformer.transform(new DOMSource(doc), new StreamResult(
					new PrintStream(archivo)));

		} catch (ParserConfigurationException e) {
			e.printStackTrace();
		} catch (TransformerConfigurationException e) {
			e.printStackTrace();
		} catch (TransformerFactoryConfigurationError e) {
			e.printStackTrace();
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (TransformerException e) {
			e.printStackTrace();
		}
	}

	private static AvionCivil recuperar(String archivo) {
		try {
		
			Document doc = DocumentBuilderFactory.newInstance()
					.newDocumentBuilder().parse(new File(archivo));
			Element element = doc.getDocumentElement();

			AvionCivil nave = AvionCivil.fromElement(element);
			return nave;
		
		} catch (SAXException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} catch (ParserConfigurationException e) {
			e.printStackTrace();
		}
	
		return null;
	}



	public void testPersistencia() {

		String archivo = "avionCivil_java.xml";
		AvionCivil naveOriginal = new AvionCivil(5,40);
		assertTrue(naveOriginal.estaVivo());
		persistir(archivo, naveOriginal);
		AvionCivil naveRecuperada = recuperar(archivo);
		assertEquals(5,naveRecuperada.getX());
		assertEquals(40,naveRecuperada.getY());
		assertFalse(naveRecuperada.verLealtad());
		assertTrue(naveRecuperada.estaVivo());
	
//		System.out.println(naveRecuperada.getClass());
	}
	
}




